home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / varie / uae-0_64.lha / uae-0.6.4 / src / fpp.c < prev    next >
C/C++ Source or Header  |  1996-09-02  |  27KB  |  1,138 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * MC68881 emulation
  5.   *
  6.   * Copyright 1996 Herman ten Brugge
  7.   */
  8.  
  9. #include <math.h>
  10.  
  11. #include "sysconfig.h"
  12. #include "sysdeps.h"
  13.  
  14. #include "config.h"
  15. #include "options.h"
  16. #include "events.h"
  17. #include "gui.h"
  18. #include "memory.h"
  19. #include "custom.h"
  20. #include "newcpu.h"
  21. #include "ersatz.h"
  22. #include "readcpu.h"
  23.  
  24. #if CPU_LEVEL >= 2
  25.  
  26. #define    DEBUG_FPP    0
  27.  
  28. /* single   : S  8*E 23*F */
  29. /* double   : S 11*E 52*F */
  30. /* extended : S 15*E 64*F */
  31. /* E = 0 & F = 0 -> 0 */
  32. /* E = MAX & F = 0 -> Infin */
  33. /* E = MAX & F # 0 -> NotANumber */
  34. /* E = biased by 127 (single) ,1023 (double) ,16383 (extended) */
  35.  
  36. static __inline__ double
  37. to_single(ULONG value)
  38. {
  39.     double frac;
  40.  
  41.     if ((value & 0x7fffffff) == 0) return(0.0);
  42.     frac = (double)((value & 0x7fffff) | 0x800000) / 8388608.0;
  43.     if (value & 0x80000000) frac = -frac;
  44.     return(ldexp(frac, ((value >> 23) & 0xff) - 127));
  45. }
  46.  
  47. static __inline__ ULONG
  48. from_single(double src)
  49. {
  50.     int expon;
  51.     ULONG tmp;
  52.     double frac;
  53.  
  54.     if (src == 0.0) return 0;
  55.     if (src < 0) { tmp = 0x80000000 ; src = -src; }
  56.     else { tmp = 0; }
  57.     frac = frexp(src,&expon);
  58.     frac += 0.5 / 16777216.0;
  59.     if (frac >= 1.0) { frac /= 2.0; expon++; }
  60.     return (tmp | (((expon + 127 - 1) & 0xff) << 23) |
  61.         (((int)(frac * 16777216.0)) & 0x7fffff));
  62. }
  63.  
  64. static __inline__ double
  65. to_exten(ULONG wrd1,ULONG wrd2,ULONG wrd3)
  66. {
  67.     double frac;
  68.  
  69.     if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) return 0.0;
  70.     frac = (double)wrd2 / 2147483648.0 +
  71.            (double)wrd3 / 9223372036854775808.0;
  72.     if (wrd1 & 0x80000000) frac = -frac;
  73.     return ldexp(frac, ((wrd1 >> 16) & 0x7fff) - 16383);
  74. }
  75.  
  76. static __inline__ void
  77. from_exten(double src,ULONG *wrd1, ULONG *wrd2, ULONG * wrd3)
  78. {
  79.     int expon;
  80.     double frac;
  81.  
  82.     if (src == 0.0) { *wrd1 = 0; *wrd2 = 0; *wrd3 = 0; return; }
  83.     if (src < 0) { *wrd1 = 0x80000000 ; src = -src; }
  84.     else { *wrd1 = 0; }
  85.     frac = frexp(src,&expon);
  86.     frac += 0.5 / 18446744073709551616.0;
  87.     if (frac >= 1.0) { frac /= 2.0; expon++; }
  88.     *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
  89.     *wrd2 = (ULONG)(frac * 4294967296.0);
  90.     *wrd3 = (ULONG)(frac * 18446744073709551616.0 - *wrd2 * 4294967296.0);
  91. }
  92.  
  93. static __inline__ double
  94. to_double(ULONG wrd1,ULONG wrd2)
  95. {
  96.     double frac;
  97.  
  98.     if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) return 0.0;
  99.     frac = (double)((wrd1 & 0xfffff) | 0x100000) / 1048576.0 +
  100.            (double)wrd2 / 4503599627370496.0;
  101.     if (wrd1 & 0x80000000) frac = -frac;
  102.     return ldexp(frac, ((wrd1 >> 20) & 0x7ff) - 1023);
  103. }
  104.  
  105. static __inline__ void
  106. from_double(double src,ULONG *wrd1, ULONG *wrd2)
  107. {
  108.     int expon;
  109.     int tmp;
  110.     double frac;
  111.  
  112.     if (src == 0.0) { *wrd1 = 0; *wrd2 = 0; return; }
  113.     if (src < 0) { *wrd1 = 0x80000000 ; src = -src; }
  114.     else { *wrd1 = 0; }
  115.     frac = frexp(src,&expon);
  116.     frac += 0.5 / 9007199254740992.0;
  117.     if (frac >= 1.0) { frac /= 2.0; expon++; }
  118.     tmp = (ULONG)(frac * 2097152.0);
  119.     *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff);
  120.     *wrd2 = (ULONG)(frac * 9007199254740992.0 - tmp * 4294967296.0);
  121. }
  122.  
  123. static __inline__ double
  124. to_pack(ULONG wrd1,ULONG wrd2,ULONG wrd3)
  125. {
  126.     double d;
  127.     char *cp;
  128.     char str[100];
  129.  
  130.     cp = str;
  131.     if (wrd1 & 0x80000000) *cp++ = '-';
  132.     *cp++ = (wrd1 & 0xf) + '0';
  133.     *cp++ = '.';
  134.     *cp++ = ((wrd2 >> 28) & 0xf) + '0';
  135.     *cp++ = ((wrd2 >> 24) & 0xf) + '0';
  136.     *cp++ = ((wrd2 >> 20) & 0xf) + '0';
  137.     *cp++ = ((wrd2 >> 16) & 0xf) + '0';
  138.     *cp++ = ((wrd2 >> 12) & 0xf) + '0';
  139.     *cp++ = ((wrd2 >> 8) & 0xf) + '0';
  140.     *cp++ = ((wrd2 >> 4) & 0xf) + '0';
  141.     *cp++ = ((wrd2 >> 0) & 0xf) + '0';
  142.     *cp++ = ((wrd3 >> 28) & 0xf) + '0';
  143.     *cp++ = ((wrd3 >> 24) & 0xf) + '0';
  144.     *cp++ = ((wrd3 >> 20) & 0xf) + '0';
  145.     *cp++ = ((wrd3 >> 16) & 0xf) + '0';
  146.     *cp++ = ((wrd3 >> 12) & 0xf) + '0';
  147.     *cp++ = ((wrd3 >> 8) & 0xf) + '0';
  148.     *cp++ = ((wrd3 >> 4) & 0xf) + '0';
  149.     *cp++ = ((wrd3 >> 0) & 0xf) + '0';
  150.     *cp++ = 'E';
  151.     if (wrd1 & 0x40000000) *cp++ = '-';
  152.     *cp++ = ((wrd1 >> 24) & 0xf) + '0';
  153.     *cp++ = ((wrd1 >> 20) & 0xf) + '0';
  154.     *cp++ = ((wrd1 >> 16) & 0xf) + '0';
  155.     *cp = 0;
  156.     sscanf(str,"%le",&d);
  157.     return d;
  158. }
  159.  
  160. static __inline__ void
  161. from_pack(double src,ULONG *wrd1, ULONG *wrd2, ULONG * wrd3)
  162. {
  163.     int i;
  164.     int t;
  165.     char *cp;
  166.     char str[100];
  167.  
  168.     sprintf(str,"%.16e",src);
  169.     cp = str;
  170.     *wrd1 = *wrd2 = *wrd3 = 0;
  171.     if (*cp == '-') { cp++ ; *wrd1 = 0x80000000; }
  172.     if (*cp == '+') cp++;
  173.     *wrd1 |= (*cp++ - '0');
  174.     if (*cp == '.') cp++;
  175.     for (i = 0 ; i < 8 ; i++) {
  176.         *wrd2 <<= 4;
  177.         if (*cp >= '0' && *cp <= '9')
  178.             *wrd2 |= *cp++ - '0';
  179.     }
  180.     for (i = 0 ; i < 8 ; i++) {
  181.         *wrd3 <<= 4;
  182.         if (*cp >= '0' && *cp <= '9')
  183.             *wrd3 |= *cp++ - '0';
  184.     }
  185.     if (*cp == 'e' || *cp == 'E') {
  186.         cp++;
  187.         if (*cp == '-') { cp++; *wrd1 |= 0x40000000; }
  188.         if (*cp == '+') cp++;
  189.         t = 0;
  190.         for (i = 0 ; i < 3 ; i++) {
  191.             if (*cp >= '0' && *cp <= '9')
  192.                 t = (t << 4) | (*cp++ - '0');
  193.         }
  194.         *wrd1 |= t << 16;
  195.     }
  196. }
  197.  
  198. static __inline__ int
  199. get_fp_value(ULONG opcode, UWORD extra,double *src)
  200. {
  201.     int size;
  202.     int mode;
  203.     int reg;
  204.     ULONG ad = 0;
  205.     static int sz1[8] = { 4,4,12,12,2,8,1,0 };
  206.     static int sz2[8] = { 4,4,12,12,2,8,2,0 };
  207.  
  208.     if ((extra & 0x4000) == 0) {
  209.         *src = regs.fp[(extra >> 10) & 7];
  210.         return 1;
  211.     }
  212.     mode = (opcode >> 3) & 7;
  213.     reg = opcode & 7;
  214.     size = (extra >> 10) & 7;
  215.     switch (mode) {
  216.     case 0:
  217.         switch (size) {
  218.         case 6: *src = (double)(BYTE)regs.d[reg];
  219.             break;
  220.         case 4: *src = (double)(WORD)regs.d[reg];
  221.             break;
  222.         case 0: *src = (double)(LONG)regs.d[reg];
  223.             break;
  224.         case 1: *src = to_single(regs.d[reg]);
  225.             break;
  226.         default:
  227.             return 0;
  228.         }
  229.         return 1;
  230.     case 1:
  231.         return 0;
  232.     case 2:
  233.         ad = regs.a[reg];
  234.         break;
  235.     case 3:
  236.         ad = regs.a[reg];
  237.         regs.a[reg] += reg == 7 ? sz2[size] : sz1[size];
  238.         break;
  239.     case 4:
  240.         regs.a[reg] -= reg == 7 ? sz2[size] : sz1[size];
  241.         ad = regs.a[reg];
  242.         break;
  243.     case 5:
  244.         ad = regs.a[reg] + (LONG)(WORD)nextiword();
  245.         break;
  246.     case 6:
  247.         ad = get_disp_ea(regs.a[reg]);
  248.         break;
  249.     case 7:
  250.         switch (reg) {
  251.         case 0: ad = (LONG)(WORD)nextiword();
  252.             break;
  253.         case 1: ad = nextilong();
  254.             break;
  255.         case 2: ad = m68k_getpc();
  256.             ad += (LONG)(WORD)nextiword();
  257.             break;
  258.         case 3: ad = get_disp_ea(m68k_getpc());
  259.             break;
  260.         case 4: ad = m68k_getpc();
  261.             m68k_setpc(ad + sz2[size]);
  262.             break;
  263.         default:
  264.             return 0;
  265.         }
  266.     }
  267.     switch (size) {
  268.     case 0: *src = (double)(LONG)get_long(ad);
  269.         break;
  270.     case 1: *src = to_single(get_long(ad));
  271.         break;
  272.     case 2:    { ULONG wrd1,wrd2,wrd3;
  273.           wrd1 = get_long(ad);ad+=4;
  274.           wrd2 = get_long(ad);ad+=4;
  275.           wrd3 = get_long(ad);
  276.           *src = to_exten(wrd1,wrd2,wrd3);
  277.         }
  278.         break;
  279.     case 3:    { ULONG wrd1,wrd2,wrd3;
  280.           wrd1 = get_long(ad);ad+=4;
  281.           wrd2 = get_long(ad);ad+=4;
  282.           wrd3 = get_long(ad);
  283.           *src = to_pack(wrd1,wrd2,wrd3);
  284.         }
  285.         break;
  286.     case 4: *src = (double)(WORD)get_word(ad);
  287.         break;
  288.     case 5:    { ULONG wrd1,wrd2;
  289.           wrd1 = get_long(ad);ad+=4;
  290.           wrd2 = get_long(ad);
  291.           *src = to_double(wrd1,wrd2);
  292.         }
  293.         break;
  294.     case 6: *src = (double)(BYTE)get_byte(ad);
  295.         break;
  296.     default:
  297.         return 0;
  298.     }
  299.     return 1;
  300. }
  301.  
  302. static __inline__ int
  303. put_fp_value(double value, ULONG opcode, UWORD extra)
  304. {
  305.     int size;
  306.     int mode;
  307.     int reg;
  308.     ULONG ad;
  309.     static int sz1[8] = { 4,4,12,12,2,8,1,0 };
  310.     static int sz2[8] = { 4,4,12,12,2,8,2,0 };
  311.  
  312.     if ((extra & 0x4000) == 0) {
  313.         regs.fp[(extra >> 10) & 7] = value;
  314.         return 1;
  315.     }
  316.     mode = (opcode >> 3) & 7;
  317.     reg = opcode & 7;
  318.     size = (extra >> 10) & 7;
  319.     ad = -1;
  320.     switch (mode) {
  321.     case 0:
  322.         switch (size) {
  323.         case 6: regs.d[reg] = ((int)value & 0xff) |
  324.                       (regs.d[reg] & ~0xff);
  325.             break;
  326.         case 4: regs.d[reg] = ((int)value & 0xffff) |
  327.                       (regs.d[reg] & ~0xffff);
  328.             break;
  329.         case 0: regs.d[reg] = (int)value;
  330.             break;
  331.         case 1: regs.d[reg] = from_single(value);
  332.             break;
  333.         default:
  334.             return 0;
  335.         }
  336.         return 1;
  337.     case 1:
  338.         return 0;
  339.     case 2:
  340.         ad = regs.a[reg];
  341.         break;
  342.     case 3:
  343.         ad = regs.a[reg];
  344.         regs.a[reg] += reg == 7 ? sz2[size] : sz1[size];
  345.         break;
  346.     case 4:
  347.         regs.a[reg] -= reg == 7 ? sz2[size] : sz1[size];
  348.         ad = regs.a[reg];
  349.         break;
  350.     case 5:
  351.         ad = regs.a[reg] + (LONG)(WORD)nextiword();
  352.         break;
  353.     case 6:
  354.         ad = get_disp_ea(regs.a[reg]);
  355.         break;
  356.     case 7:
  357.         switch (reg) {
  358.         case 0: ad = (LONG)(WORD)nextiword();
  359.             break;
  360.         case 1: ad = nextilong();
  361.             break;
  362.         case 2: ad = m68k_getpc();
  363.             ad += (LONG)(WORD)nextiword();
  364.             break;
  365.         case 3: ad = get_disp_ea(m68k_getpc());
  366.             break;
  367.         case 4: ad = m68k_getpc();
  368.             m68k_setpc(ad + sz2[size]);
  369.             break;
  370.         default:
  371.             return 0;
  372.         }
  373.     }
  374.     switch (size) {
  375.     case 0: put_long(ad,(LONG)value);
  376.         break;
  377.     case 1: put_long(ad,from_single(value));
  378.         break;
  379.     case 2:    { ULONG wrd1,wrd2,wrd3;
  380.           from_exten(value,&wrd1,&wrd2,&wrd3);
  381.           put_long(ad,wrd1);ad+=4;
  382.           put_long(ad,wrd2);ad+=4;
  383.           put_long(ad,wrd3);
  384.         }
  385.         break;
  386.     case 3:    { ULONG wrd1,wrd2,wrd3;
  387.           from_pack(value,&wrd1,&wrd2,&wrd3);
  388.           put_long(ad,wrd1);ad+=4;
  389.           put_long(ad,wrd2);ad+=4;
  390.           put_long(ad,wrd3);
  391.         }
  392.         break;
  393.     case 4: put_word(ad,(WORD)value);
  394.         break;
  395.     case 5:    { ULONG wrd1,wrd2;
  396.           from_double(value,&wrd1,&wrd2);
  397.           put_long(ad,wrd1);ad+=4;
  398.           put_long(ad,wrd2);
  399.         }
  400.         break;
  401.     case 6: put_byte(ad,(BYTE)value);
  402.         break;
  403.     default:
  404.         return 0;
  405.     }
  406.     return 1;
  407. }
  408.  
  409. static __inline__ int
  410. get_fp_ad(ULONG opcode,ULONG *ad)
  411. {
  412.     int mode;
  413.     int reg;
  414.  
  415.     mode = (opcode >> 3) & 7;
  416.     reg = opcode & 7;
  417.     switch (mode) {
  418.     case 0:
  419.     case 1:
  420.         return 0;
  421.     case 2:
  422.         *ad = regs.a[reg];
  423.         break;
  424.     case 3:
  425.         *ad = regs.a[reg];
  426.         break;
  427.     case 4:
  428.         *ad = regs.a[reg];
  429.         break;
  430.     case 5:
  431.         *ad = regs.a[reg] + (LONG)(WORD)nextiword();
  432.         break;
  433.     case 6:
  434.         *ad = get_disp_ea(regs.a[reg]);
  435.         break;
  436.     case 7:
  437.         switch (reg) {
  438.         case 0: *ad = (LONG)(WORD)nextiword();
  439.             break;
  440.         case 1: *ad = nextilong();
  441.             break;
  442.         case 2: *ad = m68k_getpc();
  443.             *ad += (LONG)(WORD)nextiword();
  444.             break;
  445.         case 3: *ad = get_disp_ea(m68k_getpc());
  446.             break;
  447.         default:
  448.             return 0;
  449.         }
  450.     }
  451.     return 1;
  452. }
  453.  
  454. static __inline__ int
  455. fpp_cond(ULONG opcode, int contition)
  456. {
  457.     int N = (regs.fpsr & 0x8000000) != 0;
  458.     int Z = (regs.fpsr & 0x4000000) != 0;
  459.     /* int I = (regs.fpsr & 0x2000000) != 0; */
  460.     int NotANumber = (regs.fpsr & 0x1000000) != 0;
  461.  
  462.     switch (contition) {
  463.     case 0x00: return 0;
  464.     case 0x01: return Z;
  465.     case 0x02: return !(NotANumber || Z || N);
  466.     case 0x03: return Z || !(NotANumber || N);
  467.     case 0x04: return N && !(NotANumber || Z);
  468.     case 0x05: return Z || (N && !NotANumber);
  469.     case 0x06: return !(NotANumber || Z);
  470.     case 0x07: return !NotANumber;
  471.     case 0x08: return NotANumber;
  472.     case 0x09: return NotANumber || Z;
  473.     case 0x0a: return NotANumber || !(N || Z);
  474.     case 0x0b: return NotANumber || Z || !N;
  475.     case 0x0c: return NotANumber || (N && !Z);
  476.     case 0x0d: return NotANumber || Z || N;
  477.     case 0x0e: return !Z;
  478.     case 0x0f: return 1;
  479.     case 0x10: return 0;
  480.     case 0x11: return Z;
  481.     case 0x12: return !(NotANumber || Z || N);
  482.     case 0x13: return Z || !(NotANumber || N);
  483.     case 0x14: return N && !(NotANumber || Z);
  484.     case 0x15: return Z || (N && !NotANumber);
  485.     case 0x16: return !(NotANumber || Z);
  486.     case 0x17: return !NotANumber;
  487.     case 0x18: return NotANumber;
  488.     case 0x19: return NotANumber || Z;
  489.     case 0x1a: return NotANumber || !(N || Z);
  490.     case 0x1b: return NotANumber || Z || !N;
  491.     case 0x1c: return NotANumber || (Z && N);
  492.     case 0x1d: return NotANumber || Z || N;
  493.     case 0x1e: return !Z;
  494.     case 0x1f: return 1;
  495.     }
  496.     return -1;
  497. }
  498.  
  499. void
  500. fdbcc_opp(ULONG opcode, UWORD extra)
  501. {
  502.     CPTR pc = (ULONG)m68k_getpc();
  503.     LONG disp = (LONG)(WORD)nextiword();
  504.     int cc;
  505.  
  506. #if DEBUG_FPP
  507.     printf("fdbcc_opp at %08lx\n",m68k_getpc());fflush(stdout);
  508. #endif
  509.     cc = fpp_cond(opcode, extra & 0x3f);
  510.     if (cc == -1) {
  511.         m68k_setpc(pc-2);
  512.         op_illg(opcode);
  513.     }
  514.     else if (!cc) {
  515.         regs.d[opcode & 0x7] = (regs.d[opcode & 0x7] & ~0xffff) |
  516.                        ((regs.d[opcode & 0x7]-1) & 0xffff);
  517.         if ((regs.d[opcode & 0x7] & 0xffff) == 0xffff)
  518.             m68k_setpc(pc + disp);
  519.     }
  520. }
  521.  
  522. void
  523. fscc_opp(ULONG opcode, UWORD extra)
  524. {
  525.     ULONG ad;
  526.     int cc;
  527.  
  528. #if DEBUG_FPP
  529.     printf("fscc_opp at %08lx\n",m68k_getpc());fflush(stdout);
  530. #endif
  531.     cc = fpp_cond(opcode, extra & 0x3f);
  532.     if (cc == -1) {
  533.         m68k_setpc(m68k_getpc()-2);
  534.         op_illg(opcode);
  535.     }
  536.     else if ((opcode & 0x38) == 0) {
  537.         regs.d[opcode & 7] = (regs.d[opcode & 7] & ~0xff) |
  538.                         (cc ? 0xff : 0x00);
  539.     }
  540.     else {
  541.         if (get_fp_ad(opcode,&ad) == 0) {
  542.             m68k_setpc(m68k_getpc()-2);
  543.             op_illg(opcode);
  544.         }
  545.         else
  546.             put_byte(ad,cc ? 0xff : 0x00);
  547.     }
  548. }
  549.  
  550. void
  551. ftrapcc_opp(ULONG opcode, CPTR oldpc)
  552. {
  553.     int cc;
  554.  
  555. #if DEBUG_FPP
  556.     printf("ftrapcc_opp at %08lx\n",m68k_getpc());fflush(stdout);
  557. #endif
  558.     cc = fpp_cond(opcode, opcode & 0x3f);
  559.     if (cc == -1) {
  560.         m68k_setpc(oldpc);
  561.         op_illg(opcode);
  562.     }
  563.     if (cc)
  564.         Exception(7,oldpc-2);
  565. }
  566.  
  567. void
  568. fbcc_opp(ULONG opcode, CPTR pc, ULONG extra)
  569. {
  570.     int cc;
  571.  
  572. #if DEBUG_FPP
  573.     printf("fbcc_opp at %08lx\n",m68k_getpc());fflush(stdout);
  574. #endif
  575.     cc = fpp_cond(opcode, opcode & 0x3f);
  576.     if (cc == -1) {
  577.         m68k_setpc(pc);
  578.         op_illg(opcode);
  579.     }
  580.     else if (cc) {
  581.         if ((opcode & 0x40) == 0)
  582.             extra = (LONG)(WORD)extra;
  583.         m68k_setpc(pc + extra);
  584.     }
  585. }
  586.  
  587. void
  588. fsave_opp(ULONG opcode)
  589. {
  590.     ULONG ad;
  591.     int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
  592.     int i;
  593.     
  594. #if DEBUG_FPP
  595.     printf("fsave_opp at %08lx\n",m68k_getpc());fflush(stdout);
  596. #endif
  597.     if (get_fp_ad(opcode,&ad) == 0) {
  598.         op_illg(opcode);
  599.         return;
  600.     }
  601.     if (incr < 0) {
  602.         ad -= 4;put_long(ad,0x70000000);
  603.         for (i = 0 ; i < 5 ; i++) {
  604.             ad -= 4;put_long(ad,0x00000000);
  605.         }
  606.         ad -= 4;put_long(ad,0x1f180000);
  607.     }
  608.     else {
  609.         put_long(ad,0x1f180000); ad += 4;
  610.         for (i = 0 ; i < 5 ; i++) {
  611.             put_long(ad,0x00000000); ad += 4;
  612.         }
  613.         put_long(ad,0x70000000); ad += 4;
  614.     }
  615.     if ((opcode & 0x38) == 0x18) regs.a[opcode & 7] = ad;
  616.     if ((opcode & 0x38) == 0x20) regs.a[opcode & 7] = ad;
  617. }
  618.  
  619. void
  620. frestore_opp(ULONG opcode)
  621. {
  622.     ULONG ad;
  623.     ULONG d;
  624.     int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
  625.     
  626. #if DEBUG_FPP
  627.     printf("frestore_opp at %08lx\n",m68k_getpc());fflush(stdout);
  628. #endif
  629.     if (get_fp_ad(opcode,&ad) == 0) {
  630.         op_illg(opcode);
  631.         return;
  632.     }
  633.     if (incr < 0) {
  634.         ad -= 4; d = get_long(ad);
  635.         if ((d & 0xff000000) != 0) {
  636.             if ((d & 0x00ff0000) == 0x00180000)
  637.                 ad -= 6 * 4;
  638.             else if ((d & 0x00ff0000) == 0x00380000)
  639.                 ad -= 14 * 4;
  640.             else if ((d & 0x00ff0000) == 0x00b40000)
  641.                 ad -= 45 * 4;
  642.         }
  643.     }
  644.     else {
  645.         d = get_long(ad); ad += 4;
  646.         if ((d & 0xff000000) != 0) {
  647.             if ((d & 0x00ff0000) == 0x00180000)
  648.                 ad += 6 * 4;
  649.             else if ((d & 0x00ff0000) == 0x00380000)
  650.                 ad += 14 * 4;
  651.             else if ((d & 0x00ff0000) == 0x00b40000)
  652.                 ad += 45 * 4;
  653.         }
  654.     }
  655.     if ((opcode & 0x38) == 0x18) regs.a[opcode & 7] = ad;
  656.     if ((opcode & 0x38) == 0x20) regs.a[opcode & 7] = ad;
  657. }
  658.  
  659. void
  660. fpp_opp(ULONG opcode, UWORD extra)
  661. {
  662.     int reg;
  663.     double src;
  664.  
  665. #if DEBUG_FPP
  666.     printf("FPP %04lx %04x at %08lx\n",opcode & 0xffff,extra & 0xffff,
  667.                        m68k_getpc()-4);fflush(stdout);
  668. #endif
  669.     switch ((extra >> 13) & 0x7) {
  670.     case 3:
  671.         if (put_fp_value(regs.fp[(extra >> 7) & 7], opcode, extra)== 0){
  672.             m68k_setpc(m68k_getpc()-2);
  673.             op_illg(opcode);
  674.         }
  675.         return;
  676.     case 4:
  677.     case 5:
  678.         if ((opcode & 0x38) == 0) {
  679.             if (extra & 0x2000) {
  680.                 if (extra & 0x1000)
  681.                     regs.d[opcode & 7] = regs.fpcr;
  682.                 if (extra & 0x0800)
  683.                     regs.d[opcode & 7] = regs.fpsr;
  684.                 if (extra & 0x0400)
  685.                     regs.d[opcode & 7] = regs.fpiar;
  686.             }
  687.             else {
  688.                 if (extra & 0x1000)
  689.                     regs.fpcr = regs.d[opcode & 7];
  690.                 if (extra & 0x0800)
  691.                     regs.fpsr = regs.d[opcode & 7];
  692.                 if (extra & 0x0400)
  693.                     regs.fpiar = regs.d[opcode & 7];
  694.             }
  695.         }
  696.         else if ((opcode & 0x38) == 1) {
  697.             if (extra & 0x2000) {
  698.                 if (extra & 0x1000)
  699.                     regs.a[opcode & 7] = regs.fpcr;
  700.                 if (extra & 0x0800)
  701.                     regs.a[opcode & 7] = regs.fpsr;
  702.                 if (extra & 0x0400)
  703.                     regs.a[opcode & 7] = regs.fpiar;
  704.             }
  705.             else {
  706.                 if (extra & 0x1000)
  707.                     regs.fpcr = regs.a[opcode & 7];
  708.                 if (extra & 0x0800)
  709.                     regs.fpsr = regs.a[opcode & 7];
  710.                 if (extra & 0x0400)
  711.                     regs.fpiar = regs.a[opcode & 7];
  712.             }
  713.         }
  714.         else if ((opcode & 0x3f) == 0x3c) {
  715.             if ((extra & 0x2000) == 0) {
  716.                 if (extra & 0x1000)
  717.                     regs.fpcr = nextilong();
  718.                 if (extra & 0x0800)
  719.                     regs.fpsr = nextilong();
  720.                 if (extra & 0x0400)
  721.                     regs.fpiar = nextilong();
  722.             }
  723.         }
  724.         else if (extra & 0x2000) {
  725.             /* FMOVEM FPP->memory */
  726.             ULONG ad;
  727.             int incr = 0;
  728.  
  729.             if (get_fp_ad(opcode,&ad) == 0) {
  730.                 m68k_setpc(m68k_getpc()-2);
  731.                 op_illg(opcode);
  732.                 return;
  733.             }
  734.             if ((opcode & 0x38) == 0x20) { 
  735.                 if (extra & 0x1000) incr += 4;
  736.                 if (extra & 0x0800) incr += 4;
  737.                 if (extra & 0x0400) incr += 4;
  738.             }
  739.             ad -= incr;
  740.             if (extra & 0x1000) {
  741.                 put_long(ad,regs.fpcr);ad+=4;
  742.             }
  743.             if (extra & 0x0800) {
  744.                 put_long(ad,regs.fpsr);ad+=4;
  745.             }
  746.             if (extra & 0x0400) {
  747.                 put_long(ad,regs.fpiar);ad+=4;
  748.             }
  749.             ad -= incr;
  750.             if ((opcode & 0x38) == 0x18) regs.a[opcode & 7] = ad;
  751.             if ((opcode & 0x38) == 0x20) regs.a[opcode & 7] = ad;
  752.         }
  753.         else {
  754.             /* FMOVEM memory->FPP */
  755.             ULONG ad;
  756.  
  757.             if (get_fp_ad(opcode,&ad) == 0) {
  758.                 m68k_setpc(m68k_getpc()-2);
  759.                 op_illg(opcode);
  760.                 return;
  761.             }
  762.             ad = (opcode & 0x38) == 0x20 ? ad-12 : ad;
  763.             if (extra & 0x1000) {
  764.                 regs.fpcr = get_long(ad);ad+=4;
  765.             }
  766.             if (extra & 0x0800) {
  767.                 regs.fpsr = get_long(ad);ad+=4;
  768.             }
  769.             if (extra & 0x0400) {
  770.                 regs.fpiar = get_long(ad);ad+=4;
  771.             }
  772.             if ((opcode & 0x38) == 0x18) regs.a[opcode & 7] = ad;
  773.             if ((opcode & 0x38) == 0x20) regs.a[opcode & 7] = ad-12;
  774.         }
  775.         return;
  776.     case 6:
  777.     case 7:
  778.         {
  779.             ULONG ad,list = 0;
  780.             int incr = 0;
  781.             if (extra & 0x2000) {
  782.             /* FMOVEM FPP->memory */
  783.             if (get_fp_ad(opcode,&ad) == 0) {
  784.                 m68k_setpc(m68k_getpc()-2);
  785.                 op_illg(opcode);
  786.                 return;
  787.             }
  788.             switch ((extra >> 11) & 3) {
  789.             case 0:    /* static pred */
  790.                 list = extra & 0xff;
  791.                 incr = -1;
  792.                 break;
  793.             case 1: /* dynamic pred */
  794.                 list = regs.d[(extra >> 4) & 3] & 0xff;
  795.                 incr = -1;
  796.                 break;
  797.             case 2: /* static postinc */
  798.                 list = extra & 0xff;
  799.                 incr = 1;
  800.                 break;
  801.             case 3: /* dynamic postinc */
  802.                 list = regs.d[(extra >> 4) & 3] & 0xff;
  803.                 incr = 1;
  804.                 break;
  805.             }
  806.             while (list) {
  807.                 ULONG wrd1,wrd2,wrd3;
  808.                 if (incr < 0) {
  809.                     from_exten(
  810.                         regs.fp[fpp_movem_index2[list]],
  811.                         &wrd1,&wrd2,&wrd3);
  812.                     ad-=4;put_long(ad,wrd3);
  813.                     ad-=4;put_long(ad,wrd2);
  814.                     ad-=4;put_long(ad,wrd1);
  815.                 }
  816.                 else {
  817.                     from_exten(
  818.                         regs.fp[fpp_movem_index1[list]],
  819.                         &wrd1,&wrd2,&wrd3);
  820.                     put_long(ad,wrd1);ad+=4;
  821.                     put_long(ad,wrd2);ad+=4;
  822.                     put_long(ad,wrd3);ad+=4;
  823.                 }
  824.                 list = fpp_movem_next[list];
  825.             }
  826.             if ((opcode & 0x38) == 0x18) regs.a[opcode & 7] = ad;
  827.             if ((opcode & 0x38) == 0x20) regs.a[opcode & 7] = ad;
  828.             }
  829.             else {
  830.             /* FMOVEM memory->FPP */
  831.             if (get_fp_ad(opcode,&ad) == 0) {
  832.                 m68k_setpc(m68k_getpc()-2);
  833.                 op_illg(opcode);
  834.                 return;
  835.             }
  836.             switch ((extra >> 11) & 3) {
  837.             case 0:    /* static pred */
  838.                 list = extra & 0xff;
  839.                 incr = -1;
  840.                 break;
  841.             case 1: /* dynamic pred */
  842.                 list = regs.d[(extra >> 4) & 3] & 0xff;
  843.                 incr = -1;
  844.                 break;
  845.             case 2: /* static postinc */
  846.                 list = extra & 0xff;
  847.                 incr = 1;
  848.                 break;
  849.             case 3: /* dynamic postinc */
  850.                 list = regs.d[(extra >> 4) & 3] & 0xff;
  851.                 incr = 1;
  852.                 break;
  853.             }
  854.             while (list) {
  855.                 ULONG wrd1,wrd2,wrd3;
  856.                 if (incr < 0) {
  857.                     ad-=4;wrd3 = get_long(ad);
  858.                     ad-=4;wrd2 = get_long(ad);
  859.                     ad-=4;wrd1 = get_long(ad);
  860.                     regs.fp[fpp_movem_index2[list]] =
  861.                         to_exten(wrd1,wrd2,wrd3);
  862.                 }
  863.                 else {
  864.                     wrd1 = get_long(ad);ad+=4;
  865.                     wrd2 = get_long(ad);ad+=4;
  866.                     wrd3 = get_long(ad);ad+=4;
  867.                     regs.fp[fpp_movem_index1[list]] =
  868.                         to_exten(wrd1,wrd2,wrd3);
  869.                 }
  870.                 list = fpp_movem_next[list];
  871.             }
  872.             if ((opcode & 0x38) == 0x18) regs.a[opcode & 7] = ad;
  873.             if ((opcode & 0x38) == 0x20) regs.a[opcode & 7] = ad;
  874.             }
  875.         }
  876.         return;
  877.     case 0:
  878.     case 2:
  879.         reg = (extra >> 7) & 7;
  880.         if ((extra & 0xfc00) == 0x5c00) {
  881.             switch (extra & 0x7f) {
  882.             case 0x00: regs.fp[reg] = 4.0*atan(1.0); break;
  883.             case 0x0b: regs.fp[reg] = log10(2.0); break;
  884.             case 0x0c: regs.fp[reg] = exp(1.0); break;
  885.             case 0x0d: regs.fp[reg] = log(exp(1.0))/log(2.0); break;
  886.             case 0x0e: regs.fp[reg] = log(exp(1.0))/log(10.0); break;
  887.             case 0x0f: regs.fp[reg] = 0.0; break;
  888.             case 0x30: regs.fp[reg] = log(2.0); break;
  889.             case 0x31: regs.fp[reg] = log(10.0); break;
  890.             case 0x32: regs.fp[reg] = 1.0e0; break;
  891.             case 0x33: regs.fp[reg] = 1.0e1; break;
  892.             case 0x34: regs.fp[reg] = 1.0e2; break;
  893.             case 0x35: regs.fp[reg] = 1.0e4; break;
  894.             case 0x36: regs.fp[reg] = 1.0e8; break;
  895.             case 0x37: regs.fp[reg] = 1.0e16; break;
  896.             case 0x38: regs.fp[reg] = 1.0e32; break;
  897.             case 0x39: regs.fp[reg] = 1.0e64; break;
  898.             case 0x3a: regs.fp[reg] = 1.0e128; break;
  899.             case 0x3b: regs.fp[reg] = 1.0e256; break;
  900. #if 0
  901.             case 0x3c: regs.fp[reg] = 1.0e512; break;
  902.             case 0x3d: regs.fp[reg] = 1.0e1024; break;
  903.             case 0x3e: regs.fp[reg] = 1.0e2048; break;
  904.             case 0x3f: regs.fp[reg] = 1.0e4096; break;
  905. #endif
  906.             default:
  907.                 m68k_setpc(m68k_getpc()-2);
  908.                 op_illg(opcode);
  909.                 break;
  910.             }
  911.             return;
  912.         }
  913.         if (get_fp_value(opcode, extra, &src) == 0) {
  914.             m68k_setpc(m68k_getpc()-2);
  915.             op_illg(opcode);
  916.             return;
  917.         }
  918.         switch (extra & 0x7f) {
  919.         case 0x00:    /* FMOVE */
  920.             regs.fp[reg] = src;
  921.             break;
  922.         case 0x01:    /* FINT */
  923.             regs.fp[reg] = (int)(src + 0.5);
  924.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  925.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  926.             break;
  927.         case 0x02:    /* FSINH */
  928.             regs.fp[reg] = sinh(src);
  929.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  930.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  931.             break;
  932.         case 0x03:    /* FINTRZ */
  933.             regs.fp[reg] = (int)src;
  934.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  935.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  936.             break;
  937.         case 0x04:    /* FSQRT */
  938.             regs.fp[reg] = sqrt(src);
  939.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  940.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  941.             break;
  942.         case 0x06:    /* FLOGNP1 */
  943.             regs.fp[reg] = log(src + 1.0);
  944.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  945.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  946.             break;
  947.         case 0x08:    /* FETOXM1 */
  948.             regs.fp[reg] = exp(src) - 1.0;
  949.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  950.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  951.             break;
  952.         case 0x09:    /* FTANH */
  953.             regs.fp[reg] = tanh(src);
  954.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  955.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  956.             break;
  957.         case 0x0a:    /* FATAN */
  958.             regs.fp[reg] = atan(src);
  959.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  960.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  961.             break;
  962.         case 0x0c:    /* FASIN */
  963.             regs.fp[reg] = asin(src);
  964.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  965.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  966.             break;
  967.         case 0x0d:    /* FATANH */
  968. #ifdef __bebox__
  969.             printf("atanh\n");
  970. #else
  971.             regs.fp[reg] = atanh(src);
  972. #endif
  973.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  974.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  975.             break;
  976.         case 0x0e:    /* FSIN */
  977.             regs.fp[reg] = sin(src);
  978.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  979.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  980.             break;
  981.         case 0x0f:    /* FTAN */
  982.             regs.fp[reg] = tan(src);
  983.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  984.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  985.             break;
  986.         case 0x10:    /* FETOX */
  987.             regs.fp[reg] = exp(src);
  988.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  989.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  990.             break;
  991.         case 0x11:    /* FTWOTOX */
  992.             regs.fp[reg] = pow(2.0,src);
  993.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  994.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  995.             break;
  996.         case 0x12:    /* FTENTOX */
  997.             regs.fp[reg] = pow(10.0,src);
  998.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  999.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1000.             break;
  1001.         case 0x14:    /* FLOGN */
  1002.             regs.fp[reg] = log(src);
  1003.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1004.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1005.             break;
  1006.         case 0x15:    /* FLOG10 */
  1007.             regs.fp[reg] = log10(src);
  1008.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1009.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1010.             break;
  1011.         case 0x16:    /* FLOG2 */
  1012.             regs.fp[reg] = log(src) / log(2.0);
  1013.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1014.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1015.             break;
  1016.         case 0x18:    /* FABS */
  1017.             regs.fp[reg] = src < 0 ? -src : src;
  1018.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1019.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1020.             break;
  1021.         case 0x19:    /* FCOSH */
  1022.             regs.fp[reg] = cosh(src);
  1023.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1024.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1025.             break;
  1026.         case 0x1a:    /* FNEG */
  1027.             regs.fp[reg] = -src;
  1028.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1029.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1030.             break;
  1031.         case 0x1c:    /* FACOS */
  1032.             regs.fp[reg] = acos(src);
  1033.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1034.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1035.             break;
  1036.         case 0x1d:    /* FCOS */
  1037.             regs.fp[reg] = cos(src);
  1038.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1039.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1040.             break;
  1041.         case 0x1e:    /* FGETEXP */
  1042.             { int expon;
  1043.             frexp(src,&expon);
  1044.             regs.fp[reg] = (double)(expon-1);
  1045.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1046.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1047.             }
  1048.             break;
  1049.         case 0x1f:    /* FGETMAN */
  1050.             { int expon;
  1051.             regs.fp[reg] = frexp(src,&expon) * 2.0;
  1052.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1053.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1054.             }
  1055.             break;
  1056.         case 0x20:    /* FDIV */
  1057.             regs.fp[reg] /= src;
  1058.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1059.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1060.             break;
  1061.         case 0x21:    /* FMOD */
  1062.             regs.fp[reg] = regs.fp[reg] - 
  1063.                 (double)((int)(regs.fp[reg] / src)) * src;
  1064.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1065.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1066.             break;
  1067.         case 0x22:    /* FADD */
  1068.             regs.fp[reg] += src;
  1069.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1070.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1071.             break;
  1072.         case 0x23:    /* FMUL */
  1073.             regs.fp[reg] *= src;
  1074.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1075.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1076.             break;
  1077.         case 0x24:    /* FSGLDIV */
  1078.             regs.fp[reg] /= src;
  1079.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1080.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1081.             break;
  1082.         case 0x25:    /* FREM */
  1083.             regs.fp[reg] = regs.fp[reg] - 
  1084.                 (double)((int)(regs.fp[reg] / src + 0.5)) * src;
  1085.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1086.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1087.             break;
  1088.         case 0x26:    /* FSCALE */
  1089.             regs.fp[reg] *= exp(log(2.0)*src);
  1090.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1091.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1092.             break;
  1093.         case 0x27:    /* FSGLMUL */
  1094.             regs.fp[reg] *= src;
  1095.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1096.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1097.             break;
  1098.         case 0x28:    /* FSUB */
  1099.             regs.fp[reg] -= src;
  1100.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1101.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1102.             break;
  1103.         case 0x30:    /* FSINCOS */
  1104.         case 0x31:
  1105.         case 0x32:
  1106.         case 0x33:
  1107.         case 0x34:
  1108.         case 0x35:
  1109.         case 0x36:
  1110.         case 0x37:
  1111.             regs.fp[reg] = sin(src);
  1112.             regs.fp[extra & 7] = cos(src);
  1113.             regs.fpsr = (regs.fp[reg] == 0 ? 0x4000000 : 0) |
  1114.                     (regs.fp[reg] < 0 ? 0x8000000 : 0);
  1115.             break;
  1116.         case 0x38:    /* FCMP */
  1117.             { double tmp = regs.fp[reg] - src;
  1118.             regs.fpsr = (tmp == 0 ? 0x4000000 : 0) |
  1119.                     (tmp < 0 ? 0x8000000 : 0);
  1120.             }
  1121.             break;
  1122.         case 0x3a:    /* FTST */
  1123.             regs.fpsr = (src == 0 ? 0x4000000 : 0) |
  1124.                     (src < 0 ? 0x8000000 : 0);
  1125.             break;
  1126.         default:
  1127.             m68k_setpc(m68k_getpc()-2);
  1128.             op_illg(opcode);
  1129.             break;
  1130.         }
  1131.         return;
  1132.     }
  1133.     m68k_setpc(m68k_getpc()-2);
  1134.     op_illg(opcode);
  1135. }
  1136.  
  1137. #endif
  1138.